﻿using System;
using System.Xml;
using XmlStudio.DataLayer;
using XmlStudio.Interfaces;
using XmlStudio.Models.Events;
using XmlStudio.Utilities;

namespace XmlStudio.Models.Actions {
    /// <summary>
    /// Changes the value of the text node.
    /// </summary>
    internal sealed class ModifyTextNodeAction : XmlModelAction {
        #region Fields
        #region Private
        /// <summary>
        /// <see cref="BigXmlNode"/> which value to modify.
        /// </summary>
        private BigXmlNodeInternal node;

        /// <summary>
        /// Old node's value.
        /// </summary>
        private string oldText;

        /// <summary>
        /// New value.
        /// </summary>
        private string newText;
        #endregion
        #endregion

        #region Constructors
        #region Public
        /// <summary>
        /// Initializes a new instance of the <see cref="ModifyTextNodeAction"/> class.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="node"><see cref="BigXmlNode"/> with text node.</param>
        /// <param name="newText">New text value to set.</param>
        public ModifyTextNodeAction(IXmlModelWithNotifications model, BigXmlNodeInternal node, string newText)
            : base(model) {
            this.oldText = node.XmlNode.Value;
            this.newText = newText;
            this.node = node;
            this.wasModified = this.node.Modified;
            this.address = node.Address.DeepClone<int[]>();
        }
        #endregion
        #endregion

        #region Methods
        #region Protected
        /// <summary>
        /// Executes the action.
        /// </summary>
        protected override void ExecuteCore() {
            this.node.XmlNode.Value = this.newText;
            this.node.SetModified(true);

            this.model.SetModified(true);
            this.model.OnNodeUpdated(new NodeUpdatedEventArgs<BigXmlNode>(this.node));
            this.model.OnRawXmlChanged(new RawXmlChangedEventArgs());
        }

        /// <summary>
        /// Executes the undo of this action.
        /// </summary>
        protected override void UnExecuteCore() {
            this.node.XmlNode.Value = this.oldText;
            this.node.SetModified(this.wasModified);

            this.model.SetModified(this.modelWasModified);
            this.model.OnRawXmlChanged(new RawXmlChangedEventArgs());
            this.model.OnNodeUpdated(new NodeUpdatedEventArgs<BigXmlNode>(this.node));
        }
        #endregion
        #endregion
    }
}